﻿#ifndef _C_RTSPCLIENT_H_INCLUDE_
#define _C_RTSPCLIENT_H_INCLUDE_

#include "rtsp_common.h"
#include "h264source.h"

#include <QUdpSocket>
#include <QTcpSocket>
#include <QTimer>
#include <QByteArray>

class CRtspServer;

class CRtspClient : public QTcpSocket
{
    Q_OBJECT

public:
    explicit CRtspClient(QObject *parent = nullptr,
                         qintptr socketDescriptor=-1);
    ~CRtspClient();

    inline void setRtspServer(CRtspServer *server) { m_rtspServer = server; }
    inline CRtspServer* getRtspServer(void) { return m_rtspServer; }
    inline QString getSuffix(void) { return m_rtp_suffix; }
    inline void setConnectionMode(ConnectionMode cm) { m_ConnectionMode = cm; }
    inline ConnectionMode getConnectionMode(void) { return m_ConnectionMode; }

    /// 发送数据
    qint64 send(QByteArray data);
    qint64 send2(const char *data,qint32 size);
    /// 发送UDP数据
    qint64 sendUdpData(RtpPacket *pkt);
    /// 发送UDP数据2
    qint64 sendUdpData2(QByteArray* data);
    void SetFrameType(uint8_t frameType = 0);
    void SetRtpHeader(RtpPacket *pkt);
    inline H264Source* getH264Source(void) { return &m_H264Source; }
    /// 处理视频帧
    bool HandleFrame(AVFrame *frame);

signals:
    //void sockConnected(qintptr conn);
    void sockDisConnect(qintptr conn);
    /// 处理网络二进制消息
    void signalsNetBinary(qintptr conn,QByteArray data);
    /// 日志消息
    void sockLog(QString log);

private slots:
    /// 处理接收数据
    void onReadyRead();
    /// 处理连接关闭
    void onDisconnected();
    /// 处理连接成功
    void onConnected();
    /// 处理rtsp端口数据接收
    void reciverPendingRtspDatagram();
    /// 心跳处理
    void handleHeartTimeOut();

private:
    bool HandleRtspRequest(QByteArray data);
    void HandleCmdOption(void);
    void HandleCmdDescribe();
    void HandleCmdAnnounce();
    void HandleCmdSetup();
    void HandleCmdRecord(void);
    void HandleCmdTeardown();
    void HandleCmdPlay();

    const char* GetSdpMessage(void);
    int BuildServerErrorRes(const char* buf, int buf_size);
    int BuildDescribeRes(const char* buf, int buf_size, const char* sdp);
    uint32_t GetRtpSessionId();

private:
    QByteArray m_reciverByteArray;
    tagPacket m_reciverPacket;
    quint32 m_reciverPacketSize;
    bool m_isreciverPacketHeader;
    CRtspServer *m_rtspServer;
    ConnectionMode m_ConnectionMode;
    H264Source m_H264Source;
    qintptr m_clientID;
    Method m_method;
    QString m_url,m_version;
    quint32 m_cseq;
    quint16 m_rtp_port,m_rtcp_port,m_serRtpPort,m_serRtcpPort;
    quint16 m_port,m_packet_seq;
    QString m_rtp_ip,m_rtp_suffix;
    QUdpSocket m_rtpUdpSocket,m_rtcpUdpSocket;
    RtpHeader m_RtpHeader;
    QTimer m_HeartTimeOutTimer;
    bool has_key_frame_,is_play,m_is_readyFinished;
};

#endif // CRTSPCLIENT_H
